﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using TD.Interface.Controls;

namespace TD.Interface.Menus
{
    partial class Highscores : MenuBase
    {
        private delegate void DrawMethod(ref int i);
        private Texture2D texture;
        private Texture2D background;
        private TimeSpan elapsedTime;

        public Highscores(Game1 game) :
            base(game)
        {
            base.DrawOrder = 0x08100010;

#if DEBUG
            //Management.Reset();
            //SetHighscore(200, 2, "debug #3");
#endif
        }

        public override void Initialize()
        {
            elapsedTime = new TimeSpan(0);
            
            base.Initialize();
        }

        protected override void LoadContent()
        {
            // Load the background image.
            ((Game1)Game).TextureManager.LoadAsset("interface\\menu_background");
            background = ((Game1)Game).TextureManager.UseAsset("interface\\menu_background");

            // The background for the rows.
            texture = ((Game1)Game).TextureManager.UseAsset("white");
            
            base.LoadContent();
        }

        public override void Update(GameTime gameTime)
        {
            elapsedTime += gameTime.ElapsedGameTime;

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            // Draw the menu background.
            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.Opaque);
            spriteBatch.Draw(background, new Rectangle(0, 0, 1280, 720), Color.White);
            spriteBatch.End();

            // First draw the backgrounds of the scoring players.
            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
            Draw_Callback(new DrawMethod(Draw_HighscoreBackground));
            spriteBatch.End();

            // Second draw the text on top of the backgrounds of the players.
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            Draw_Callback(new DrawMethod(Draw_HighscoreFont));
            spriteBatch.End();

            base.Draw(gameTime);
        }

        // Called for drawing the highscore components.
        private void Draw_Callback(DrawMethod method)
        {
            for (int i = 0; i < 13; i++) // The ammount of highscors being drawn.
            {
                if ((i * 500) <= elapsedTime.TotalMilliseconds) // The interval between adding a new row.
                {
                    method.Invoke(ref i);
                }
            }
        }

        // Get the offset for each of the rows in the highscores.
        private int GetOffset(int i)
        {
            int y = (32 * i) + 100;

            if (i == 0) return 0x00 + y;
            if (i == 1) return 0x30 + y;
            if (i == 2) return 0x50 + y;
            return 0x60 + y;
        }

        // Draws the background for the players in the highscores.
        private void Draw_HighscoreBackground(ref int i)
        {
            Color color;

            // Special background for the first three players.
            if (i == 0)
            {
                color = Color.Gold;
            }
            else if (i == 1)
            {
                color = Color.Silver;
            }
            else if (i == 2)
            {
                color = Color.Brown;
            }
            else if ((i & 1) > 0)
            {
                color = Color.FromNonPremultiplied(0x28, 0x77, 0xA2, 0xFF);
            }
            else
            {
                color = Color.FromNonPremultiplied(0x33, 0x51, 0xAC, 0xFF);
            }

            int y = GetOffset(i);

            spriteBatch.Draw(texture, new Rectangle(140, y, 1000, 32), color);
        }

        // Draws the text of the players in the highscores.
        private void Draw_HighscoreFont(ref int i)
        {
            HSData data = Management.Data(i);
            int y = GetOffset(i);

            Color color = Color.White;
            if (i == 0) color = Color.FromNonPremultiplied(0x20, 0x20, 0x20, 0xFF); // 1st Place
            if (i == 1) color = Color.FromNonPremultiplied(0x20, 0x20, 0x20, 0xFF); // 2nd Place

            spriteBatch.DrawString(base.subFont, data.Name, new Vector2(144, y + 4), color);
            spriteBatch.DrawString(base.subFont, data.Score.ToString(), new Vector2(540, y + 4), color);
            spriteBatch.DrawString(base.subFont, data.Wave.ToString(), new Vector2(600, y + 4), color);
        }

        protected override List<DrawableGameComponent> AddItems()
        {
            List<DrawableGameComponent> items = new List<DrawableGameComponent>();
            {
                // Back button.
                ButtonBack back = new ButtonBack((Game1)Game);
                back.MouseClick += new ButtonBase.OnClick(this.Back_MouseClick);
                items.Add(back);
                back.DrawOrder = this.DrawOrder + 1;
            }
            return items;
        }

        private void Back_MouseClick(object sender)
        {
            // Close the highscores menu.
            ExitMenu();
        }

        protected override void HandleEnabledChanged(object sender, EventArgs e)
        {
            // Do something...
        }

        protected override void HandleVisibleChanged(object sender, EventArgs e)
        {
            if (base.Visible)
            {
                // Reset the amount of time elapsed, so we can restart the animation upon re-entering.
                elapsedTime = new TimeSpan(0);
            }
        }

        protected override void UpdateItems(List<DrawableGameComponent> items, GameTime gameTime)
        {
            // Do something...
        }

        public static void SetHighscore(int score, int wave, string name)
        {
            HSData data = new HSData();
            data.Score = score;
            data.Wave = wave;
            data.Name = name;
            Management.Data(data);
        }
    }
}
